home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ply15dat.zip / GEARS.C < prev    next >
C/C++ Source or Header  |  1992-10-26  |  7KB  |  219 lines

  1. /*
  2.  * gears.c - Create a set of gears.  Each gear face has 144 vertices, and
  3.  *   contains concavities.  Note that the first 3 vertices of all polygons
  4.  *   define the two edges of a convex section of the polygon.  Background
  5.  *   square floor is reflective.  Some gears are clipped.
  6.  *   Five light sources.
  7.  *
  8.  * Version:  2.2 (11/17/87)
  9.  * Author:  Eric Haines, 3D/Eye, Inc.
  10.  *
  11.  * SIZE_FACTOR determines the number of polygons output.
  12.  *     Total gears = SF**3:  concave polygons = 2 * SF**3
  13.  *     rectangles = 4*TEETH * SF**3
  14.  *
  15.  * SIZE_FACTOR   # gears # gear faces    # rectangles
  16.  *       1          1          2           144
  17.  *       2          8         16          1152
  18.  *       3         27         54          3888
  19.  *       4         64        128          9216
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <math.h>
  24. #ifdef MAC
  25. #include <console.h>
  26. #endif
  27. #include "def.h"
  28. #include "lib.h"
  29.  
  30. #define SIZE_FACTOR 2
  31.  
  32. /* define number of teeth on a gear - must be a multiple of 4 */
  33. #define TEETH 32
  34. /* define ratio of radius taken up by teeth and the gear thickness */
  35. #define EDGE_RATIO   0.1
  36. #define DEPTH_RATIO  0.1
  37.  
  38. /* Create gear tooth */
  39. static void
  40. create_tooth(double gear_angle, double tooth_angle,
  41.         COORD4 *center, COORD4 *outer_pt,
  42.         COORD4 *inner_pt, COORD4 *edge_pts)
  43. {
  44.     MATRIX   mx ;
  45.  
  46.  
  47.     lib_create_rotate_matrix( mx
  48.              , Z_AXIS
  49.              , gear_angle - 0.19 * tooth_angle ) ;
  50.     lib_transform_coord( &edge_pts[0], outer_pt, mx ) ;
  51.     ADD2_COORD( edge_pts[0], *center ) ;
  52.     lib_create_rotate_matrix( mx
  53.              , Z_AXIS
  54.              , gear_angle + 0.19 * tooth_angle ) ;
  55.     lib_transform_coord( &edge_pts[1], outer_pt, mx ) ;
  56.     ADD2_COORD( edge_pts[1], *center ) ;
  57.     lib_create_rotate_matrix( mx
  58.              , Z_AXIS
  59.              , gear_angle + 0.3 * tooth_angle ) ;
  60.     lib_transform_coord( &edge_pts[2], inner_pt, mx ) ;
  61.     ADD2_COORD( edge_pts[2], *center ) ;
  62.     lib_create_rotate_matrix( mx
  63.              , Z_AXIS
  64.              , gear_angle + 0.7 * tooth_angle ) ;
  65.     lib_transform_coord( &edge_pts[3], inner_pt, mx ) ;
  66.     ADD2_COORD( edge_pts[3], *center ) ;
  67. }
  68.  
  69.  
  70. /* Create gear */
  71. static void
  72. create_gear(COORD4 *center, double offset_angle, double outer_radius,
  73.        double inner_radius, double thickness)
  74. {
  75.     COORD4   side_pts[4], gear_pts[4*TEETH], outer_pt, inner_pt ;
  76.     long   next_side, num_side, num_teeth ;
  77.     double   gear_angle, tooth_angle ;
  78.  
  79.  
  80.     outer_pt.x = outer_radius ;
  81.     outer_pt.y = 0.0 ;
  82.     outer_pt.z = 0.0 ;
  83.     outer_pt.w = 1.0 ;
  84.     inner_pt.x = inner_radius ;
  85.     inner_pt.y = 0.0 ;
  86.     inner_pt.z = 0.0 ;
  87.     inner_pt.w = 1.0 ;
  88.  
  89.     tooth_angle = 2.0 * PI / (double)TEETH ;
  90.  
  91.     /* output gear top */
  92.     for ( num_teeth = 0 ; num_teeth < TEETH ; ++num_teeth ) {
  93.    gear_angle = offset_angle +
  94.       2.0 * PI * (double)num_teeth / (double)TEETH ;
  95.    create_tooth( gear_angle
  96.           , tooth_angle
  97.           , center
  98.           , &outer_pt
  99.           , &inner_pt
  100.           , &gear_pts[num_teeth*4]
  101.           ) ;
  102.     }
  103.     lib_output_polygon(4*TEETH, gear_pts);
  104.  
  105.     /* output teeth */
  106.     for ( num_side = 0 ; num_side < 4 * TEETH ; ++num_side ) {
  107.    next_side = ( num_side + 1 ) % ( 4 * TEETH ) ;
  108.    COPY_COORD( side_pts[0], gear_pts[num_side] ) ;
  109.    COPY_COORD( side_pts[1], gear_pts[num_side] ) ;
  110.    side_pts[1].z -= thickness ;
  111.    COPY_COORD( side_pts[2], gear_pts[next_side] ) ;
  112.    side_pts[2].z -= thickness ;
  113.    COPY_COORD( side_pts[3], gear_pts[next_side] ) ;
  114.    lib_output_polygon(4, side_pts);
  115.     }
  116.  
  117.     /* output gear bottom */
  118.     outer_pt.z = inner_pt.z = -thickness ;
  119.     for ( num_teeth = 0 ; num_teeth < TEETH ; ++num_teeth ) {
  120.    gear_angle = offset_angle -
  121.       2.0 * PI * (double)num_teeth / (double)TEETH ;
  122.    create_tooth( gear_angle
  123.           , -tooth_angle
  124.           , center
  125.           , &outer_pt
  126.           , &inner_pt
  127.           , &gear_pts[num_teeth*4]
  128.           ) ;
  129.     }
  130.     lib_output_polygon(4*TEETH, gear_pts);
  131. }
  132.  
  133. void
  134. main(int argc, char *argv[])
  135. {
  136.    COORD4  back_color, gear_color ;
  137.    COORD4  center_pt, floor[4], light, offset, zero_pt ;
  138.    COORD4  from, at, up, dir;
  139.    double  angle, color_scale, outer_radius, thickness ;
  140.    long    ix, iy, iz ;
  141.  
  142.    /* We are using Polyray */
  143.    lib_set_raytracer(OUTPUT_POLYRAY);
  144.  
  145.    /* output viewpoint */
  146.    SET_COORD( from, -1.1, -2.1, 2.6 ) ;
  147.    SET_COORD( at, 0.0, 0.0, 0.0 ) ;
  148.    SET_COORD( up, 0.0, 0.0, 1.0 ) ;
  149.    lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
  150.  
  151.    /* output background color - UNC sky blue */
  152.    SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
  153.    lib_output_background_color( &back_color ) ;
  154.  
  155.    /* output light sources */
  156.    SET_COORD4( light, 2.0, 4.0, 4.0, 0.45 ) ;
  157.    lib_output_light( &light ) ;
  158.    SET_COORD4( light, -2.0, 4.0, 3.0, 0.45 ) ;
  159.    lib_output_light( &light ) ;
  160.    SET_COORD4( light, 2.0, -2.5, 2.5, 0.45 ) ;
  161.    lib_output_light( &light ) ;
  162.    SET_COORD4( light, -1.0, -4.0, 2.0, 0.45 ) ;
  163.    lib_output_light( &light ) ;
  164.    /* just behind the eye */
  165.    SET_COORD4( light, -1.111, -2.121, 2.626, 0.45 ) ;
  166.    lib_output_light( &light ) ;
  167.  
  168.    /* output floor polygon - off white */
  169.    SET_COORD( back_color, 1.0, 0.85, 0.7 ) ;
  170.    lib_output_color(&back_color, 0.1, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0);
  171.    SET_COORD( floor[0], 2.0, 2.0, 0.0 ) ;
  172.    SET_COORD( floor[1], -2.0, 2.0, 0.0 ) ;
  173.    SET_COORD( floor[2], -2.0, -2.0, 0.0 ) ;
  174.    SET_COORD( floor[3], 2.0, -2.0, 0.0 ) ;
  175.    lib_output_polygon(4, floor);
  176.  
  177.    outer_radius = 1.0 / ((double)SIZE_FACTOR -
  178.              (double)(SIZE_FACTOR - 1) * EDGE_RATIO / 2.0);
  179.    /* calculate first gear center */
  180.    zero_pt.x = zero_pt.y = -1.0 + outer_radius ;
  181.    zero_pt.z = 1.0 ;
  182.    /* calculate offset */
  183.    offset.x = offset.y = outer_radius * ( 2.0 - EDGE_RATIO ) ;
  184.    offset.z = -1.0 / (double)SIZE_FACTOR ;
  185.  
  186.     /* create gears */
  187.    for ( iz = 0 ; iz < SIZE_FACTOR ; ++iz ) {
  188.       center_pt.z = zero_pt.z + (double)iz * offset.z ;
  189.       for ( iy = 0 ; iy < SIZE_FACTOR ; ++iy ) {
  190.          center_pt.y = zero_pt.y + (double)iy * offset.y ;
  191.          for ( ix = 0 ; ix < SIZE_FACTOR ; ++ix ) {
  192.             center_pt.x = zero_pt.x + (double)ix * offset.x ;
  193.  
  194.             /* output pseudo-random gear color */
  195.             SET_COORD(gear_color,
  196.                       0.01 + FRACTION( (double)(ix*3+iy*2+iz+1)*5.0/7.0 ),
  197.                       0.01 + FRACTION( (double)(iy*3+iz*2+ix+1)*3.0/7.0 ),
  198.                       0.01 + FRACTION( (double)(iz*3+ix*2+iy+1)*2.0/7.0 ));
  199.             color_scale = MAX3( gear_color.x, gear_color.y, gear_color.z );
  200.             gear_color.x /= color_scale ;
  201.             gear_color.y /= color_scale ;
  202.             gear_color.z /= color_scale ;
  203.             if ((ix*4 + iy*2 + iz ) % 5 == 0)
  204.                lib_output_color(&gear_color, 0.1, 0.2, 0.0, 0.0, 0.0,
  205.                                 0.7, 1.1);
  206.             else
  207.                lib_output_color(&gear_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
  208.  
  209.  
  210.             /* output gear */
  211.             angle = PI * (double)( (ix+iy+iz) % 2 ) / (double)(TEETH);
  212.             thickness = MIN( DEPTH_RATIO, 1.0 / ( 2.0 * (double)SIZE_FACTOR));
  213.             create_gear(¢er_pt, angle, outer_radius,
  214.                         (1.0 - EDGE_RATIO) * outer_radius, thickness);
  215.             }
  216.          }
  217.       }
  218. }
  219.